﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlTypes;
using Noris.Schedule.Support.Data;
using Noris.Schedule.Support.Sql;
using System.Data.SqlClient;

namespace Noris.Schedule.UI.Expressions
{
    #region CLASS SchedulerConfigCls : Třída odvozená z tabulky lcs.scheduler_config,      rozšířeno o další property !!!
    /// <summary>
    /// SchedulerConfigCls : Data z Master tabulky třídy 1963: Konfigurace modulu Scheduler (SchedulerConfigInst), Nonsubjektová
    /// Data načtena z tabulky lcs.scheduler_config
    /// </summary>
    public partial class SchedulerConfigCls : RecordCls, IDbRecord
    {
        #region KONSTRUKTORY
        /// <summary>
        /// Implicitní konstruktor, zajistí číslování záznamů do jednotné Temporary řady
        /// </summary>
        public SchedulerConfigCls()
            : base()
        { }
        /// <summary>
        /// Konstruktor s načítáním dat z databáze
        /// </summary>
        /// <param name="recordNumber">Číslo záznamu, který je třeba načíst</param>
        public SchedulerConfigCls(int recordNumber)
            : base(recordNumber)
        { }
        /// <summary>
        /// Explicitní konstruktor, dovolí zvolit, zda se pro tento záznam bude generovat Temporary ID
        /// </summary>
        /// <param name="createTemporaryId">true pokud se pro záznam má vytvořit Temporary ID.
        /// Default (false) = nevytvoří se, bude mít RecordNumber = 0.</param>
        public SchedulerConfigCls(bool createTemporaryId)
            : base(createTemporaryId)
        { }
        #endregion
        #region PUBLIC OVERRIDE PROPERTY
        /// <summary>Číslo třídy (1963)</summary>
        public override int ClassNumber { get { return ClassNr; } }
        /// <summary>Číslo třídy (1963)</summary>
        public const int ClassNr = 1963;
        /// <summary>Číslo záznamu = cislo_nonsubjektu</summary>
        public override int RecordNumber { get { return base._cislo_nonsubjektu; } }
        /// <summary>IDbRecord.RecordNumber : musí konkrétně implementovat set, protože DbLayer po uložení nového záznamu (kde RecordNumber == 0) do něj vloží přidělený klíč</summary>
        int IDbRecord.RecordNumber
        {
            get { return this.RecordNumber; }
            set { base._cislo_nonsubjektu = value; }
        }
        #endregion
        #region PUBLIC DATA PROPERTY
        ///<summary><para>Atribut: Typ údaje, podmnožina v rámci Skupiny. Pro skupinu = 1 (Konfigurované texty): 1 = text prvku (Text)  2 = doplňující text (ToolTipText)</para><para>Db: lcs.scheduler_config.typ (int null)</para></summary>
        public SqlInt32 Typ { get { return _typ; } set { _typ = value; IsDirty = true; } }
        ///<summary><para>Atribut: Klíč údaje. Pro konfigurované texty je zde uložen klíč konkrétního druhu elementů, pro který tato konfigurace platí. Klíč pochází z interface IConfiguredText, z property string ConfigurationKey.</para><para>Db: lcs.scheduler_config.klic (varchar (40) null)</para></summary>
        public string Klic { get { return _klic; } set { _klic = value; IsDirty = true; } }
        ///<summary><para>Atribut: Skupina údaje. 1 = Konfigurovaný text</para><para>Db: lcs.scheduler_config.skupina (int null)</para></summary>
        public SqlInt32 Skupina { get { return _skupina; } set { _skupina = value; IsDirty = true; } }
        ///<summary><para>Atribut: Název položky</para><para>Db: lcs.scheduler_config.nazev (varchar (40) null)</para></summary>
        public new string Nazev { get { return _nazev; } set { _nazev = value; IsDirty = true; } }
        ///<summary><para>Atribut: Popis / ukázka</para><para>Db: lcs.scheduler_config.popis (varchar (1000) null)</para></summary>
        public string Popis { get { return _popis; } set { _popis = value; IsDirty = true; } }
        ///<summary><para>Atribut: Text konfigurace</para><para>Db: lcs.scheduler_config.text (varchar (-1) null)</para></summary>
        public string Text { get { return _text; } set { _text = value; IsDirty = true; } }
        ///<summary><para>Atribut: Datum vzniku [Datum_cas]</para><para>Db: lcs.scheduler_config.datum_vzniku (datetime null)</para></summary>
        public SqlDateTime DatumVzniku { get { return _datum_vzniku; } set { _datum_vzniku = value; IsDirty = true; } }
        ///<summary><para>Atribut: Datum posl. aktualizace [Datum_cas]</para><para>Db: lcs.scheduler_config.last_update (datetime null)</para></summary>
        public SqlDateTime LastUpdate { get { return _last_update; } set { _last_update = value; IsDirty = true; } }
        ///<summary><para>Vztah 105396: Vytvořil (zprava: Vytvořil - Konfig.  Scheduler)</para><para>Db: lcs.scheduler_config.created_by (int null)</para></summary>
        public SqlInt32 CreatedBy { get { return _created_by; } set { _created_by = value; IsDirty = true; } }
        ///<summary><para>Vztah 105397: Pachatel poslední změny (zprava: Pachatel - Konfig.  Scheduler)</para><para>Db: lcs.scheduler_config.pachatel (int null)</para></summary>
        public SqlInt32 Pachatel { get { return _pachatel; } set { _pachatel = value; IsDirty = true; } }
        #endregion
        #region PROTECTED DATA FIELDS
#pragma warning disable 1591
        protected SqlInt32 _typ;
        protected string _klic;
        protected SqlInt32 _skupina;
        protected string _nazev;
        protected string _popis;
        protected string _text;
        protected SqlDateTime _datum_vzniku;
        protected SqlDateTime _last_update;
        protected SqlInt32 _created_by;
        protected SqlInt32 _pachatel;
#pragma warning restore 1591
        #endregion
        #region FILL FROM READER
        /// <summary>
        /// Virtuální metoda, která umožňuje potomkům provádět typovou a rychlou konverzi dat proudících z databáze přes DataReader 
        /// přímo do objektu této třídy, bez použití generické metody FieldInfo.SetValue (která je poněkud pomalá).
        /// Tato metoda v této třídě tedy má naplnit každou svoji instanční proměnnou (field) hodnotou z předaného SqlDataReaderu.
        /// Pro snadné načtení dat je předán objekt mapper, který nabízí svou generickou metodu FillDataIntoField«int»(string dbColumnName, SqlDataReader reader).
        /// Tato metoda vrátí načtená data (typovaná jako objekt).
        /// Čtení touto metodou je cca 6x rychlejší než čtení generickou metodou.
        /// Metoda má vracet true, pokud převzala všechna data. 
        /// Je nanejvýše účelné, aby tak provedla, protože pokud vrátí false, pak se po jejím skončení provede generické ukládání dat (což je 6x pomalejší).
        /// </summary>
        /// <param name="reader">Vstupní DataReader</param>
        /// <param name="map">Mapování dat z readeru na fields tohoto objektu</param>
        /// <returns>true = data byla převzata / false = data nepřevzata</returns>
        public override bool FillFromReader(SqlDataReader reader, FieldMapperLoad map)
        {
            base.FillFromReader(reader, map);
            _typ = (SqlInt32)map.FillDataIntoField<SqlInt32>("typ", reader);
            _klic = (string)map.FillDataIntoField<string>("klic", reader);
            _skupina = (SqlInt32)map.FillDataIntoField<SqlInt32>("skupina", reader);
            _nazev = (string)map.FillDataIntoField<string>("nazev", reader);
            _popis = (string)map.FillDataIntoField<string>("popis", reader);
            _text = (string)map.FillDataIntoField<string>("text", reader);
            _datum_vzniku = (SqlDateTime)map.FillDataIntoField<SqlDateTime>("datum_vzniku", reader);
            _last_update = (SqlDateTime)map.FillDataIntoField<SqlDateTime>("last_update", reader);
            _created_by = (SqlInt32)map.FillDataIntoField<SqlInt32>("created_by", reader);
            _pachatel = (SqlInt32)map.FillDataIntoField<SqlInt32>("pachatel", reader);
            return true;
        }
        #endregion
        #region SAVE RECORD
        /// <summary>
        /// Zajistí přípravu svých dat do podkladové vrstvy pro uložení do databáze.
        /// Subjektové třídy musí nejprve volat SubjectCls.PrepareSaveData(this, map);, 
        /// tím se uloží data do tabulky subjektů (a pro nové záznamy se vygeneruje číslo subjektu).
        /// Nonsubjektové třídy to volat nesmí.
        /// </summary>
        /// <param name="map"></param>
        /// <returns></returns>
        public override bool PrepareSaveData(FieldMapperSave map)
        {
            map.AddTable("lcs.scheduler_config", "cislo_nonsubjektu");
            map.AddColumn("typ", this.Typ);
            map.AddColumn("klic", this.Klic);
            map.AddColumn("skupina", this.Skupina);
            map.AddColumn("nazev", this.Nazev);
            map.AddColumn("popis", this.Popis);
            map.AddColumn("text", this.Text);
            map.AddColumn("datum_vzniku", this.DatumVzniku);
            map.AddColumn("last_update", this.LastUpdate);
            map.AddColumn("created_by", this.CreatedBy);
            map.AddColumn("pachatel", this.Pachatel);
            map.AddTableEnd();
            return true;
        }
        #endregion
        #region STATIC GENERÁTORY SELECTU
        /// <summary>
        /// SQL SELECT pro načtení columnů, odpovídajících této struktuře. Pozor: neobsahuje filtr ani order.
        /// </summary>
        public static new string SqlSelect { get { return @"SELECT * FROM lcs.scheduler_config"; } }
        /// <summary>
        /// Jméno sloupce, který obsahuje klíč záznamu, určeno pro filtry.
        /// </summary>
        public static new string SqlRecord { get { return "cislo_nonsubjektu"; } }
        /// <summary>
        /// Generátor SELECTU pro načítání do CACHE.
        /// Vrátí SQL SELECT, který používá SysCache pro automatické načítání záznamů do cache.
        /// Vrácený select má tvar "SELECT * FROM tabulka [join lcs.subjekty] WHERE [master_tabulka.]key_column", cache si doplní číslo[a] záznamů sama.
        /// </summary>
        /// <returns>Vrátí SQL SELECT, který používá SysCache pro automatické načítání záznamů do cache.</returns>
        public override string GetCacheSelect()
        {
            return SqlSelect + " WHERE " + SqlRecord;
        }
        #endregion
        #region Rozšířené property nad rámec RecordCls, odlišné overrides
        /// <summary>Reference: roli reference hraje Klic.</summary>
        public override string Reference { get { return _klic; } protected set { _klic = value; IsDirty = true; } }
        // PS : ve standardních public property je ještě změna:      public string Nazev   =>    public override string Nazev
        #endregion
        #region Overrides
        /// <summary>
        /// Háček po uložení dat do SQL.
        /// </summary>
        public override void SaveAfter(RecordClsEventArgs args)
        {
            base.SaveAfter(args);
            // Zajistíme invalidaci dat v paměti:
            Noris.Schedule.Support.Expressions.SchedulerConfigData.Invalidate(this.Skupina, this.Klic);
        }
        #endregion
    }
    #endregion
}
